﻿/** \file
* \$Rev$
* 
* \$Date$
*
* \$URL$
*/

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace BT211.AI
{
	/// <summary>
	/// A small utility class to create AI instances from an AI type.
	/// </summary>
	class AIFactory
	{
		/// <summary>The type of AI to instantiate.</summary>
		Type aitype;

		/// <summary>The constructor.</summary>
		/// <param name="aitype">The type of AI to instantiate.</param>
		public AIFactory(Type aitype)
		{
			this.aitype = aitype;
		}

		/// <summary>A new AI instance.</summary>
		public AI NewInstance {
			get {
				return (AI)System.Activator.CreateInstance(aitype);
			}
		}

		/// <summary>The name of the AI type.</summary>
		public string Name { get { return aitype.Name; } }

		/// <summary>
		/// Load factories from a set of DLLs.
		/// </summary>
		/// <param name="dirname">The directory to search for DLLs.</param>
		/// <returns>A list of the factories.</returns>
		public static List<AIFactory> LoadFactories(string dirname)
		{
			List<AIFactory> factories = new List<AIFactory>();
			string aidir = Directory.GetCurrentDirectory() + '\\' + dirname;
			try
			{
				string[] dlls = Directory.GetFiles(aidir, "*.dll", SearchOption.AllDirectories);
				foreach (string dllpath in dlls)
				{
					// Load the DLL, and remember all classes derived from AI
					Assembly dll = Assembly.LoadFile(dllpath);
					foreach (Type aitype in dll.GetTypes())
						if (aitype.IsSubclassOf(typeof(AI)))
							factories.Add(new AIFactory(aitype));
				}
			}
			catch (DirectoryNotFoundException)
			{
				// If the tanks directory doesn't exist, make it
				Directory.CreateDirectory(dirname);
			}
			return factories;
		}
	}
}
